package com.example.tofcamera;

import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.util.Log;

import java.util.concurrent.ArrayBlockingQueue;

/**
 * Created by j on 2017/2/25.
 */

public class FrameQueue extends ArrayBlockingQueue<Frame>
{
    protected int frameWidth;
    protected int frameHeight;
    protected int frameTotal;

    protected long nFrame;

    protected MediaFormat frameFormat;

    public MediaFormat getFrameFormat() {
        return frameFormat;
    }

    public void setFrameFormat(MediaFormat format) {
        this.frameFormat = format;
        frameWidth=frameFormat.getInteger(MediaFormat.KEY_WIDTH);
        frameHeight=frameFormat.getInteger(MediaFormat.KEY_HEIGHT);

//        nFrame= (long) (frameFormat.getLong(MediaFormat.KEY_DURATION)*getFrameRate()/1e6);

//        frameFormat.setInteger(MediaFormat.KEY_BIT_RATE, frameWidth * frameHeight * getFrameRate());
//        frameFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 8);

//        int colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar;
        // Set some properties.  Failing to specify some of these can cause the MediaCodec
        // configure() call to throw an unhelpful exception.
//        frameFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);

        Log.d("FrameQueue", frameFormat.toString());
        setFrameFormat(frameWidth, frameHeight, getFrameRate());
        Log.d("FrameQueue", frameFormat.toString());

        frameTotal=frameWidth*frameHeight;
    }

    public void setFrameFormat(int width, int height, int frameRate) {
        String MIME_TYPE = "video/avc";
        frameFormat = MediaFormat.createVideoFormat(MIME_TYPE, width, height);
        int IFrameInterval=8;
        int colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar;
        // Set some properties.  Failing to specify some of these can cause the MediaCodec
        // configure() call to throw an unhelpful exception.
        frameFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
        frameFormat.setInteger(MediaFormat.KEY_BIT_RATE, width * height * frameRate);
        frameFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
        frameFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFrameInterval);

        frameWidth=frameFormat.getInteger(MediaFormat.KEY_WIDTH);
        frameHeight=frameFormat.getInteger(MediaFormat.KEY_HEIGHT);

        frameTotal=frameWidth*frameHeight;
    }

    public FrameQueue(int capacity) {
        super(capacity);
    }

    @Override
    public void put(Frame frame) throws InterruptedException {
        byte[] dt=frame.getData();
        if(dt!=null && dt.length>frameTotal+(frameTotal>>1))
        {
            Log.d("FrameQueue", "have gap "+((dt.length<<1)/3/frameWidth-frameHeight));
            super.put(new Frame(TakeYUVArray(dt)));
            return;
        }
        super.put(frame);
    }

    public int getFrameRate() {
        return frameFormat.getInteger(MediaFormat.KEY_FRAME_RATE);
    }

    public int getFrameWidth() {
        return frameWidth;
    }

    public int getFrameHeight() {
        return frameHeight;
    }

    public byte[] TakeYUVArray(byte []data){
        byte[] YUV=new byte[frameTotal+(frameTotal>>1)];
        System.arraycopy(data, 0, YUV, 0, frameTotal);
        System.arraycopy(data, (data.length<<1)/3, YUV, frameTotal, frameTotal >> 1);
        return YUV;
    }

    public Frame TakeOver() throws InterruptedException {
        Frame frame=take();
        while(!isEmpty())
        {
            frame=take();
        }
        return frame;
    }

}
